﻿package net.wangit.adm.group;

import net.wangit.MapList;
import net.wangit.Row;
import net.wangit.context.ActionContext;
import net.wangit.jdbc.ColumnRow;
import net.wangit.jdbc.DB;
import net.wangit.jdbc.Table;
import net.wangit.support.action.DefaultAction;
import net.wangit.user.admin.AdminCache;
import net.wangit.user.group.UserGroupCache;
import net.wangit.util.TreeUtil;

public class SaveGroupAction extends DefaultAction {

	private static final String GROUPS_UPDATE = "update AGROUP set parentid=? where parentid=?";
	private static final String ADMINISTRATOR_UPDATE = "update AADMINGROUP set groupid=? where groupid=?";
	private static final String ROLE_UPDATE = "update AGROUPROLE set groupid=? where groupid=?";
	private static final String USER_UPDATE = "update AUSERGROUP set groupid=? where groupid=?";
	private static final String LEVEL_QUERY = "select * from AGROUP";
	private static final String LEVEL_UPDATE = "update AGROUP set grouplevel=? where groupid=?";
	private static final int LEVEL_UPDATE_TYPES[] = { 11, 2 };
	private static final String LEVEL_DELETE = "delete from AGROUPLEVEL";
	private static final String LEVEL_INSERT = "insert into AGROUPLEVEL (upperid,lowerid) values (?,?)";

	public SaveGroupAction() {
	}

	public void doAction(DB db, ActionContext ac) throws Exception {
		super.doAction(db, ac);
		ColumnRow row = (ColumnRow) ((Table) ac.getTables().get(0)).getRows()
				.get(0);
		if (row.isUpdateRow()) {
			String newId = row.get("groupid");
			String oldId = row.getPrimaryKey("groupid");
			update(db, newId, oldId);
		}
		MapList groups = db.query("select * from AGROUP");
		updateLevel(db, groups);
		insertLevel(db, groups);
		if (row.isUpdateRow()) {
			UserGroupCache.clearAll();
			AdminCache.clearAll();
		}
	}

	private void update(DB db, String newGroupId, String oldGroupId)
			throws Exception {
		if (!oldGroupId.equals(newGroupId)) {
			String values[] = { newGroupId, oldGroupId };
			int types[] = { 2, 2 };
			db.execute("update AGROUP set parentid=? where parentid=?", values,
					types);
			db.execute("update AADMINGROUP set groupid=? where groupid=?",
					values, types);
			db.execute("update AGROUPROLE set groupid=? where groupid=?",
					values, types);
			db.execute("update AUSERGROUP set groupid=? where groupid=?",
					values, types);
		}
	}

	private void updateLevel(DB db, MapList orgs) throws Exception {
		for (int i = 0; i < orgs.size(); i++) {
			String orgId = orgs.getRow(i).get("groupid");
			MapList parents = TreeUtil.getParents(orgs, orgId, "groupid",
					"parentid");
			db.execute("update AGROUP set grouplevel=? where groupid=?",
					new String[] { Integer.toString(parents.size()), orgId },
					LEVEL_UPDATE_TYPES);
		}

	}

	private void insertLevel(DB db, MapList groups) throws Exception {
		db.execute("delete from AGROUPLEVEL");
		for (int i = 0; i < groups.size(); i++) {
			String upperId = groups.getRow(i).get("groupid");
			insertLevel(db, groups, upperId, upperId);
		}

	}

	private void insertLevel(DB db, MapList groups, String upperId,
			String parentId) throws Exception {
		for (int i = 0; i < groups.size(); i++) {
			Row group = groups.getRow(i);
			if (parentId.equals(group.get("parentid"))) {
				String childId = group.get("groupid");
				db
						.execute(
								"insert into AGROUPLEVEL (upperid,lowerid) values (?,?)",
								new String[] { upperId, childId }, new int[] {
										2, 2 });
				insertLevel(db, groups, upperId, childId);
			}
		}

	}

}
